// 转义字符、以ASCII码值打印、不同注释风格
// 选择语句、循环语句、函数、数组、各类操作符、数组元素个数计算方法
#include<stdio.h>
//---------------------------------------------小节分割线--------------------------------------------

// int main()
// {
//     printf("c:\test\test.c\n");// \t被当做了转义字符（转变了原来的意思）
//     // 更多转义字符见第1节-初识C语言.pdf课件
//     printf("%d\n", 100);// %d表示打印整数
//     printf("%c\n", 'a');// %c表示打印一个字符
//     printf("%s\n", "abc");// %s表示打印一段字符串
//     printf("%s\n", "\""); // 里面一个"双引号前加一个\表示这不是一对双引号中的一个
//     printf("%s\n", "'"); 
//     printf("c:\\test\\test.c\n"); // 这样就可以打印路径了
//     return 0;
// }

//---------------------------------------------小节分割线--------------------------------------------

// int main()
// {
//     printf("%c\n",'\130'); // 格式为\ddd，ddd表示1~3个八进制数字，如\130表示X
//     // 八进制130转化为十进制为88，大写X的ASCII码值就是88
//     printf("%c\n",'\101'); // A的ASCII值为65，八进制为101 

//     printf("%c\n", '\x30');// 格式为\xdd,dd表示两个十六进制的数字，例如\x30 表示字符0，而不是数字0
//     return 0;
// }
//---------------------------------------------小节分割线--------------------------------------------
//小测，输出结果是什么？
// int main()
// {
//     printf("%d\n", strlen("abcdef"));
//     printf("%d\n", strlen("c:\test\628\test.c"));
//     return 0;
// }
//---------------------------------------------小节分割线--------------------------------------------

// 不同的注释风格
int main()
{
    // int a = 10 // C++的注释风格

    /*
    int b = 10  //C的注释风格，但是缺点是不支持嵌套注释
    */
    
    return 0;
}



//---------------------------------------------小节分割线--------------------------------------------
//初识选择语句
// int main()
// {
//     int input = 0; //用于存储输入的参数
//     printf("是否疯狂学习？请输入1或0：");
//     scanf("%d", &input); //&表示取input的地址用于存储
//     if(input == 1)
//         printf("年薪20w以上等着你！");
//     else
//         printf("高薪个屁！");
//     return 0;
// }

//---------------------------------------------小节分割线--------------------------------------------
//初识循环语句（只有while循环，for和do…while后期学）
// int main()
// {
//     //假设一共敲了代码5万行有效代码后就可以找到好工作了！
//     int line = 0; //用来存储已经敲的代码行数
//     while (line<50000)
//     {
//         printf("纯度太低了！才敲了%d行代码\n",line);
//         line = line + 100;
//     }
//     if (line>=50000)
//     {
//         printf("汪汪队赚大钱！\n");
//     }
//     return 0;
// }

//---------------------------------------------小节分割线--------------------------------------------

// 函数
// int Add(int x, int y)
// {
//     int z = 0;
//     z = x + y;
//     return z;
// }

// int main()
// {
//     int num1 = 0;
//     int num2 = 0;
//     printf("输入第一个值：");
//     scanf("%d",&num1); // 记得加&
//     printf("输入第二个值：");
//     scanf("%d",&num2);
//     printf("牛逼！现在我们把两个数加起来\n");
//     //int sum = num1 + num2;// 这是直接计算的方式，接下来使用函数的方式完成
//     int sum = Add(num1, num2);
//     printf("两个值的和为：%d", sum); 
//     return 0;
// }

//---------------------------------------------小节分割线--------------------------------------------

// 数组 - 一组相同类型的元素的集合
// int main()
// {
//     // 存储10个整形1~10
//     int arr[10] = {1,2,3,4,5,6,7,8,9,10}; // 一个空间的名字叫做arr，这个空间中存储了10个变量，每个变量的数据类型是整数int类型
//     char ch[5] = {'a', 'b', 'c'}; // 不完全初始化，剩余值默认为0
//     // 访问数组内元素时，是使用下标访问的，如arr[0]
//     int i = 0; // 打印arr数组中使用的循环标识
//     while (i<10)
//     {
//         printf("%d ",arr[i]);
//         i++;
//     }
//     return 0;
// }

//---------------------------------------------小节分割线--------------------------------------------

// 操作符，只是粗浅的了解一下
// 算术操作符  + - * / %
// 移位操作符 >> << 右移操作符，左移操作符
// 位操作符 &（按位与）    |（按位或）   ^（按位异或）
// 赋值操作符 = += -= *= /= &= ^=  |=    >>=   <<= 
// 单目操作符
// 
// int main()
// {
//     // 这部分展示 / 和 % 的效果
//     int a1 = 9/2;
//     printf("a1=%d\n",a1);
//     float a2 = 9/2;
//     printf("a2=%f\n",a2);
//     float a3 = 9/2.0;
//     printf("a3=%f\n",a3);
//     int b1 = 9%2; // %标识取模（取余）
//     printf("b1=%d\n",b1);
//     return 0;
// }

// int main()
// {
//     // 这部分展示移位操作符
//     int a = 2;
//     int b = a << 1; // 左移操作符 - 移动的是二进制位
//     // a是一个int整形，一个整形4个字节，一个字节8个比特位，a的二进制序列如下
//     // 00000000 00000000 00000000 00000010
//     // 左移一位后，最左边一位消失，最右边一位补0
//     printf("b=%d",b);
//     return 0;
// }

// int main()
// {
//     // 赋值操作符
//     int a = 2;
//     a += 5; //相当于 a = a + 5;
//     a -= 5; //相当于 a = a - 5;
//     a %= 5; //相当于 a = a % 5;
//     printf("a=%d",a);
//     return 0;
// }

// int main()
// {
//     // 单目操作符 - 与加号需要两个数才能运算不同，只需要一个操作数就可以执行
//     // 例如：!逻辑反操作   +正值  &取地址  sizeof操作数的类型长度
//     // 更多在课件第一节中看
//     //0 表示假，非0就是真，但0取反之后默认为1
//     int a = 10;
//     printf("a=10取反：%d\n",!a);
//     int b = 0;
//     printf("b=0取反：%d\n",!b);
//     // 具体可以使用在if判断中
//     if(a)
//     {
//         // 如果a为真，执行
//     }
//     if (!a)
//     {
//         // 如果a为假，执行
//     }
//     return 0;
// }

// 使用sizeof操作符可以计算出数组中元素的个数
// int main()
// {
//     // sizeof也是一个单目操作符，计算类型或者变量的大小（字节）
//     printf("int类型的大小：%d\n",sizeof(int));
//     int a = 10;
//     printf("a的大小：%d\n",sizeof a); // 这里sizeof的括号能够省略，说明sizeof确实是操作符而不是函数
//     int arr[10] = {0};
//     printf("arr的大小：%d\n",sizeof(arr)); // 计算的是数组的总大小，单位是字节
//     printf("arr[0]的大小：%d\n",sizeof(arr[0]));
//     // 使用sizeof就可以求出一个数组中元素的个数
//     int sz = sizeof(arr) / sizeof(arr[0]);
//     printf("arr中元素的个数：%d\n",sz);
//     return 0;
// }

// static int g_val = 2022; // 定义一个全局变量，为了文件2022_11_25中学习static修饰全局变量使用
// // static修饰的全局变量，使得这个全局变量只能在本源文件内使用，不能在其他源文件内使用。

int Add(int x, int y)
{
    return x + y;
}
// static int Add(int x, int y)
// {
//     return x + y;
// }

//---------------------------------------------小节分割线--------------------------------------------
// 操作符~ 对一个数的二进制按位取反
// int main()
// {
//     int a = 0;
//     printf("a按二进制取反结果：%d\n", ~a); // -1
//     // 0的二进制如何表示？
//     // 00000000 00000000 00000000 00000000  全部按位取反结果应该是32个1
//     // 整数在内存中存储的是补码
//     // 一个整数的二进制表示有3种：原码、反码、补码
//     // 正数的原码、反码、补码相同
//     // 负数的原码、反码、补码计算方式如下
//     // -1的二进制表示就是原码，最高位是符号位，剩下31个是数值位
//     // 10000000 00000000 00000000 00000001（原码）（也就是%d打印的内容）
//     // 11111111 11111111 11111111 11111110（反码）符号位不变，其他取反
//     // 11111111 11111111 11111111 11111110（补码）反码+1（也就是内存中存储的方式）
//     return 0;
// }

//---------------------------------------------小节分割线--------------------------------------------
// 前置++和后置++
// int main()
// {
//     int a = 10;
//     //int b = ++a; // 前置++  先++（改变a的值），后使用（把a的值赋给b）
//     int b = a++; // 后置++    先使用，再++
//     printf("b = %d\n", b);
//     printf("a = %d\n", a);
    
//     //printf("c = %d\n", c);
//     return 0;
// }
//---------------------------------------------小节分割线--------------------------------------------
// 强制类型转换
// int main()
// {
//     // 一般不推荐使用
//     int a = (int)3.14;
//     printf("%d\n", a);
//     return 0;
// }
//---------------------------------------------小节分割线--------------------------------------------
// 逻辑操作符
// int main()
// {
//     int a = 0;
//     int b = 5;
//     int c = a && b;
//     printf("c = %d\n", c);
//     int d = a || b;
//     printf("d = %d\n", d);
//     if (a && b)
//     {
//         printf("啊对对对a && b为真\n");
//     }
//     else 
//     {
//         printf("啊不对不对不对a && b为假\n");
//     }
    
//     return 0;
// }
//---------------------------------------------小节分割线--------------------------------------------

//条件操作符（三目操作符）
// 表达式1 ? 表达式2 : 表达式3
// 表达式1如果成立，表达式2执行计算，整个表达式的结果是表达式2的结果
// 表达式1如果不成立，表达式3执行计算，整个表达式的结果是表达式3的结果
// int main()
// {
//     int a = 0;
//     int b = 3;
//     int max = 0;
//     // if (a>b)
//     // {
//     //     max = a;
//     // }
//     // else
//     // {
//     //     max = b;
//     // } // 这是用if判断的方法，还可以用条件操作符
//     //(a > b)?(max = a):(max = b); // 还可以写成如下
//     max = a > b ? a : b;
    
//     printf("a和b的最大值：%d\n",max);
//     return 0;
// }

//---------------------------------------------小节分割线--------------------------------------------
// 逗号表达式：以此计算每个逗号，整个表达式的结果为最后一个表达式的结果

// int main()
// {
//     int a = 0;
//     int b = 3;
//     int c = 5;
//     int d = (a = b + 2, c = a - 4, b = c + 2);
//     printf("d = %d\n", d);
//     return 0;
// }

//---------------------------------------------小节分割线--------------------------------------------
// [] ()的用法
// 下标引用、函数调用和结构成员

// int main()
// {
//     int arr[10] = {1,2,3,4,5,6,7,8,9,10};

//     printf("arr[5] = %d\n",arr[5]);
//     // 这里的[]就是下标引用操作符，而printf后面的一对()就是函数调用操作符
//     return 0;
// }
// 指针、取地址操作符、解引用操作、结构体、->的使用

//---------------------------------------------小节分割线--------------------------------------------
// 指针变量的定义
// 可以在文件 内存相关知识 中看到内存是如何编号的，以及一个内存单元是多大空间。
// int main()
// {
//     int a = 10; // int类型占用空间是4个字节，a在内存中要分配的空间就是4个
//     printf("%p\n",&a); // 虽然a占用了4个地址，但是取地址a的时候，返回的是a的第一个字节的地址
//     // %p用来打印地址
//     int * pa = &a; // pa用来存放地址，C语言中pa叫做指针变量
//     // * 说明pa是指针变量
//     // int 说明pa指向的对象是int类型的
//     char ch = 'w';
//     char * pc = &ch;
//     return 0;
// }
//---------------小分割线 >.< --------------------
// int main()
// {
//     int a = 10; 
//     int * pa = &a; 
//     printf("使用地址修改前a = %d\n",a);
//     *pa = 20; // 这里的*表示解引用操作，*pa就是通过pa的地址找到a
//     printf("使用地址修改后a = %d\n",a);
//     return 0;
// }
//---------------小分割线 >.< --------------------
// int main()
// {
//     printf("%d\n",sizeof(char*));
//     printf("%d\n",sizeof(short*));
//     printf("%d\n",sizeof(int*));
//     printf("%d\n",sizeof(long*));
//     printf("%d\n",sizeof(long long*));
//     printf("%d\n",sizeof(float*));
//     printf("%d\n",sizeof(double*));
//     // 所有类型的指针大小是相同的,64位计算机的结果都是8
//     // 指针是用来存放地址的，指针有多大，取决于地址需要多大空间
//     // 32位  32bit - 4byte
//     // 64位  64bit - 8byte
// }
//---------------------------------------------小节分割线--------------------------------------------
// 结构体 - 可以创造一个复杂对象的描述类型
// 比如描述学生，学生包含： 名字+年龄+性别+学号 这几项信息

// struct Stu
// {
//     char name[20]; // 这里的name、age、score都是这个结构体的成员变量
//     int age;
//     double score;
// };

// struct Book
// {
//     char name[20];
//     float price;
//     char id[30];
// };

// int main()
// {
//     struct Stu s = {"张三", 20, 85.5}; // 结构体的创建与初始化，s就是结构体变量
//     printf("使用s直接调用：%s, %d, %f\n",s.name, s.age, s.score); // 调用方式 - 结构体变量.成员变量
//     struct Stu * ps = &s; // 这里ps就是结构体s的地址
//     printf("使用*ps调用：%s, %d, %f\n",(*ps).name, (*ps).age, (*ps).score);
//     // 注意这里*ps需要用括号括起来，才能使用 . 来调用成员变量
//     printf("使用->调用：%s, %d, %f\n",ps->name, ps->age, ps->score);// 结构体指针 -> 成员变量
//     // 使用  ->  的时候，一定要确保左边是结构体的指针，不能加*访问指针的内容
//     return 0;
// }